﻿using Microsoft.AspNetCore.DataProtection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Session;
using Microsoft.Extensions.Caching.Distributed;
using Newtonsoft.Json;
using System;
using System.Reflection;
using System.Web;

namespace vueweb
{
	public static class SessionHelper
	{
		public static string GetSessionKey(this ISession session)
		{
			Type t = session.GetType();
			FieldInfo f = t.GetField("_sessionKey", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
			string key = (string)f.GetValue(session);
			return key;
		}

		public static string GetSessionCookie(this ISession session)
		{
			return GetSessionCookie(session.GetSessionKey());
		}

		public static void SetSessionKey(this ISession session, string sessionCookie)
		{
			string key = GetSessionKey(HttpUtility.UrlDecode(sessionCookie)); 
			if (string.IsNullOrEmpty(key))
			{
				key = GetSessionKey(sessionCookie);
			}
			Type t = session.GetType();
			FieldInfo f = t.GetField("_sessionKey", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
			f.SetValue(session, key);
		}

		public static string GetSessionToken(this ISession session)
		{
			return HttpUtility.UrlEncode(session.GetSessionCookie());
		}

		public static void Abandon(this ISession session)
		{
			IDistributedCache cache = GetCache(session);
			string key = session.GetSessionKey();
			cache.Remove(key);
		}

		public static bool IfExpire(this ISession session)
		{
			IDistributedCache cache = GetCache(session);
			string key = session.GetSessionKey();
			return cache.Get(key) == null;
		}

		public static bool IfExpireOfCookie(this ISession session, string sessionCookie)
		{
			IDistributedCache cache = GetCache(session);
			string key = GetSessionKey(sessionCookie);
			return cache.Get(key) == null;
		}

		private static IDistributedCache GetCache(ISession session)
		{
			Type t = session.GetType();
			FieldInfo f = t.GetField("_cache", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
			IDistributedCache cache = (IDistributedCache)f.GetValue(session);
			return cache;
		}

		/// <summary>
		/// session用到的非对称加密的加密
		/// </summary>
		/// <param name="data"></param>
		/// <returns></returns>
		public static string Protect(string data)
		{
			return new CommonDataProtection(nameof(SessionMiddleware)).Protect(data);
		}
		/// <summary>
		/// session用到的非对称加密的解密
		/// </summary>
		/// <param name="protectedText"></param>
		/// <returns></returns>
		public static string Unprotect(string protectedText)
		{
			return new CommonDataProtection(nameof(SessionMiddleware)).Unprotect(protectedText);
		}

		public static string GetSessionKey(string cookie)
		{
			return Unprotect(cookie);
		}

		public static string GetSessionCookie(string sessionKey)
		{
			return Protect(sessionKey);
		}

		public static void Set<T>(this ISession session, string key,T v)
		{
			string str = JsonConvert.SerializeObject(v);
			session.SetString(key, str);
		}

		public static T Get<T>(this ISession session, string key)
		{
			string str = session.GetString(key);
			return JsonConvert.DeserializeObject<T>(str);
		}	
		
	}	
}
